﻿// FlmPlane
// Object representing a plane in 2D/3D space
// 
// FLMScan - Featured by FabLab Munich

using System;
using log4net;

namespace FLMScan.Geometry
{
    internal class FlmPlane
    {
        private ILog logger;

        private double a;
        private double b;
        private double c;
        private double d;

        public FlmPlane(FlmPlane plane)
        {
            logger = LogManager.GetLogger(typeof(FlmPlane));

            a = plane.A;
            b = plane.B;
            c = plane.C;
            d = plane.D;
        }

        public FlmPlane(double a, double b, double c, double d)
        {
            logger = LogManager.GetLogger(typeof(FlmPlane));

            this.a = a;
            this.b = b;
            this.c = c;
            this.d = d;
        }

        public FlmPlane(FlmPoint point1, FlmPoint point2, FlmPoint point3)
        {
            CalculatePlaneFromVectors(point1, point2, point3, true);
        }

        public FlmPlane(FlmPoint point1, FlmPoint point2, FlmPoint point3, bool normalizeDistance)
        {
            CalculatePlaneFromVectors(point1, point2, point3, normalizeDistance);
        }

        private void CalculatePlaneFromVectors(FlmPoint point1, FlmPoint point2, FlmPoint point3, bool normalizeDistance)
        {
            logger = LogManager.GetLogger(typeof(FlmPlane));

            FlmVector vector1 = new FlmVector(point1, point2);
            FlmVector vector2 = new FlmVector(point1, point3);

            FlmVector crossProduct = vector1.CrossProduct(vector2);

            // calculate normalization factor for vector crossProduct
            double normalizationFactor = 1.0 / Math.Sqrt(Math.Pow(crossProduct.X, 2) + Math.Pow(crossProduct.Y, 2) + Math.Pow(crossProduct.Z, 2));            

            a = crossProduct.X * normalizationFactor;
            b = crossProduct.Y * normalizationFactor;
            c = crossProduct.Z * normalizationFactor;

            // calculate plane distance
            double distance = -(a * point1.X + b * point1.Y + c * point1.Z);
            d = distance;

            if (normalizeDistance)
            {
                d *= normalizationFactor;
            }
        }

        public double A
        {
            get { return a; }
            set { a = value; }
        }

        public double B
        {
            get { return b; }
            set { b = value; }
        }

        public double C
        {
            get { return c; }
            set { c = value; }
        }

        public double D
        {
            get { return d; }
            set { d = value; }
        }

        public void Log(String prefix)
        {
            logger.DebugFormat("{0} FlmPlane: a:{1} b:{2} c:{3} d:{4}", prefix, A, B, C, D);
        }
    }
}
